package com.admin.service.ipl;

import com.admin.config.FastDFSClientUtil;
import com.admin.fen.Adminfenmemediafeign;
import com.admin.fen.Articlesfen;
import com.admin.mapper.AdChannelMapper;
import com.admin.service.AdsensitiveService;
import com.alibaba.fastjson.JSON;
import com.apis.ApAuthor.AdarticleApi;
import com.apis.shenhe.WemediaNewsAutoScanApi;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;

import com.admin.config.GreeTextScan;
import com.admin.config.GreenImageScan;
import com.usian.common.config.SensitiveWordUtil;
import com.usian.model.admin.pojos.AdChannel;
import com.usian.model.admin.pojos.AdSensitive;
import com.usian.model.atri.pojos.ApArticle;
import com.usian.model.atri.pojos.ApArticleConfig;
import com.usian.model.atri.pojos.ApArticleContent;
import com.usian.model.common.dtos.ResponseResult;
import com.usian.model.media.pojos.WmNews;
import com.usian.model.user.pojos.ApAuthor;

import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Transactional
@Service
public class WemediaNewsAutoScanService implements WemediaNewsAutoScanApi {

    @Resource
    private AdChannelMapper adChannelMapper;

    @Resource
    private Adminfenmemediafeign adminfenmemedia;

    @Resource
    private AdsensitiveService adsensitiveService;

//    @Resource
//    AdarticleApi adarticleApi;



    @Resource
    private GreeTextScan greeTextScan;

    @Resource
    private GreenImageScan greenImageScan;

    @Resource
    FastDFSClientUtil fastDFSClientUtil;

    @Value("${fdfs.url}")
    private String fileserverurl;

    @Resource
    Articlesfen articlesfen;

    @Resource
    private RestHighLevelClient client;


    //审核  autoScanBymedianewsid 审核的初始调用方法
    @Override
    public void autoScanBymedianewsid(Integer id) throws Exception {
//       审核第一步调用的方法 根据id获取整条记录  fegin的远程调用（admin模块下） 调用 wemediatu模块下方法
//        返回媒体对象
        System.out.println("--------------卡夫卡接收执行成功----------------");
        WmNews data = adminfenmemedia.getfindbyid(id);
        System.out.println("getfindbyid执行成功--------------------------------");
        System.out.println(data);
        /**
         * 当前状态
         0 草稿
         1 提交（待审核）
         2 审核失败
         3 人工审核
         4 人工审核通过
         8 审核通过（待发布）
         9 已发布**/

//          4 人工审核通过
        System.out.println("人工审核通过执行中-----------------------");
        if (data.getStatus() == 4) {
//      审核通过后调用三表的添加
            saveArticleAll(data);
        }
        System.out.println("人工审核通过成功-----------------------");
//  状态8 核审通过待发布  如果数据库中时间小于当前的时间 进行保存
        if (data.getStatus() == 8 && data.getPublishTime().getTime() <= System.currentTimeMillis()) {
            data.setReason("审核通过");
            data.setStatus(9);
            adminfenmemedia.updatewmnews(data);
            saveArticleAll(data);
            return;
        }
        System.out.println("核审通过待发布 -----------------------");
        System.out.println("核审过程 -----------------------");
        if (data.getStatus() == 1) {
//状态==1  提交 待审核
//            将媒体信息传入进去 返回媒体文本  以及图片的list.string
            String content = getcontent(data);
            List<String> image = getimage(data);
//            审核判断  自己数据库敏感词进行修改

            if (!wordSan(data)) {
                return;
            }
//文本审核  阿里提供的文本审核  将获取的文本   对象  传入
            if (!textSacn(data,content)) {
                return ;
            }
//            阿里云提供的图片审核  图片和媒体对象
            System.out.println("阿里云提供的图片审核-----------------");
            if (!imgsacn(image, data)) {
                return;
            }

            if (data.getPublishTime().getTime()<= System.currentTimeMillis()) {
                data.setReason("核审通过");
                data.setStatus(9);
                adminfenmemedia.updatewmnews(data);
                saveArticleAll(data);
                return;
            }else {
                data.setReason("核审通过,待发布");
                data.setStatus(8);
                adminfenmemedia.updatewmnews(data);

            }
            System.out.println("核审通过 -----------------------");


        }


    }

    //    审核图片 阿里云提供的图片自动审核 参数 图片集合 和媒体对象
    public boolean imgsacn(List<String> images, WmNews data) throws Exception {
        boolean falg = true;
        Integer status = 0;
        String msg = "";
        WmNews wmNews = new WmNews();
        List<byte[]> imagelist = new ArrayList<>();
//        将图片集合遍历  对其进行替换  将图片中的192.168.67.99 路径替换为空 让其只剩图片路径
        for (String image : images) {
            String imgname = image.replace(fileserverurl, "");
            int index = imgname.indexOf("/");
//            查询/所在的索引  并对其进行分割 找到第一个/分割
            String groupname = imgname.substring(0, index);
            String imgpath = imgname.substring(index + 1);
//            分割后再将/删除  只剩图片路径
            byte[] imgbyte = fastDFSClientUtil.download(groupname, imgpath);
            imagelist.add(imgbyte);
        }

        Map map = greenImageScan.imageScan(imagelist);
        String result = (String) map.get("suggestion");
        if (result.equals("review")) {
            status = 3;
            falg = false;
            msg = "交给人工审核";
        } else if (result.equals("block")) {
            status = 2;
            falg = false;
            msg = "图片中有敏感词";
        } else {
            status = 9;
            msg = "审核通过";
            falg = true;
        }
        wmNews.setStatus(status);
        wmNews.setReason(msg);
        if (falg) {
            adminfenmemedia.updatewmnews(wmNews);
        }
        return falg;



    }


    //数据库敏感词判断  数据库ad_sensitive
    public boolean wordSan(WmNews wmNews) {
//        定义成功 失败的返回 msg的返回 msg用来存储在媒体表中reason字段
        boolean falg = true;
        String msg = "";
//        获取敏感词列表 list.AdSensitive
        List<AdSensitive> list = adsensitiveService.findAll();
        List<String> word = new ArrayList<>();
//        创建一个新的list.string 将敏感词列表遍历 存储敏感词
        for (AdSensitive as : list) {
            word.add(as.getSensitives());
        }
//对敏感词列表进行判断是否为空
        SensitiveWordUtil.initMap(word);
//        不为空的话 将敏感词列表  查询敏感词出现 匹配的次数个数 返回map集合
        Map<String, Integer> map = SensitiveWordUtil.matchWords(getcontent(wmNews));
//        对map长度判断  >0代表有敏感词    Status（2）审核失败 msg文本传入reason字段
        if (map.size() > 0) {
            falg = false;
            msg = "文字中有敏感词";
            wmNews.setStatus(2);
            wmNews.setReason(msg);
//            对媒体表进行修改
            adminfenmemedia.updatewmnews(wmNews);
        }
//        返回true代表没有敏感词  返回false是有敏感词
        return falg;
    }


    //    核审文字  阿里提供的文本审核  str是文本
    public boolean textSacn(WmNews dao,String str) throws Exception {
        WmNews wmNews = new WmNews();
        boolean falg = true;
        Integer status = 0;
        String msg = "";
//
        Map map = greeTextScan.greeTextScan(str);
        String result = (String) map.get("suggestion");
        if (result.equals("pass")) {
            status = 9;
            msg = "核审通过";
        } else if (result.equals("block")) {
            status = 2;
            falg = false;
            msg = "文字中有敏感词";
        } else {
            status = 3;
            falg = false;
            msg = "内容不确定，提交人工审核";
        }


//        if (mapper.size()==0) {
//            status = 9;
//            msg = "核审通过";
//        } else if (mapper.size()>=1) {
//            status = 2;
//            falg = false;
//            msg = "文字中有敏感词";
//        } else {
//            status = 3;
//            falg = false;
//            msg = "内容不确定，提交人工审核";
//        }
        wmNews.setStatus(status);
        wmNews.setReason(msg);
        wmNews.setId(dao.getId());
        if (falg) {
            adminfenmemedia.updatewmnews(wmNews);
        }
        return falg;
    }


    //    媒体对象中获取文本
    public String getcontent(WmNews wmNews) {
        String str = "";
//将wmNews媒体信息中的本文图片列表中 数据转换成map 进行操作
        List<Map> maps = JSON.parseArray(wmNews.getContent(), Map.class);
//        List<Map> collect = maps.stream().collect(Collectors.toList());
        for (Map map : maps) {
//            判断map中类型是否是文本  是的话 赋值给str字符串
            if (map.get("type").equals("text")) {
                str = (String) map.get("value");
            }
        }
        return str;
    }

    //    媒体对象中获取图片
    public List<String> getimage(WmNews wmNews) {
        List<String> list = new ArrayList<>();
//        定义一个list.string 集合
        //将wmNews媒体信息中的本文图片列表中 数据转换成map 进行操作
        List<Map> maps = JSON.parseArray(wmNews.getContent(), Map.class);
//        List<Map> collect = maps.stream().collect(Collectors.toList());
        for (Map map : maps) {
            //            判断map中类型是否是图片  是的话 add添加到list.string集合中
            if (map.get("type").equals("image")) {
                list.add(map.get("value").toString());
            }
        }
        return list;
    }

    //保存数据 多张表 融合方法  主要针对文章内容
    public void saveArticleAll(WmNews wmNews) throws IOException {
//        ap_article  主表
//        ap_article_config
//        ap_article_content
        ApArticle apArticle = sevaArticle(wmNews);
//       调用 sevaArticle保存ApArticle 并返回

//        将保存成功的apArticle 和  wmNews 自媒体参数

//        两个单表的添加 ap_article_content | ap_article_config
        saveArticleconfig(wmNews, apArticle);
        saveArticlecontenet(wmNews, apArticle);
        wmNews.setArticleId(apArticle.getId());
        adminfenmemedia.updatewmnews(wmNews);

    }


    //保存ApArticle  参数是WmNews  自媒体数据
    public ApArticle sevaArticle(WmNews wmNews) throws IOException {
//        创建ApArticle 文章对象  属性赋值
        ApArticle apArticle = new ApArticle();
        apArticle.setTitle(wmNews.getTitle());
        apArticle.setLayout(wmNews.getType());
        apArticle.setChannelId(wmNews.getChannelId());
        apArticle.setImages(wmNews.getImages());
//        远程调用根据wmNews.uid去查询对应的ap_author（表）对象
        ApAuthor byId = articlesfen.findByIdapauthor(wmNews.getUserId());
//        返回的数据再次进行赋值操作
        //进行频道name查询
//        apArticle表中有ChannelName字段 上面查询是没有这个数据的 需要再次查询
        LambdaQueryWrapper<AdChannel> q = new LambdaQueryWrapper<>();
        q.eq(AdChannel::getId, wmNews.getChannelId());
        AdChannel adChannel = adChannelMapper.selectOne(q);
//        查询出AdChannel(频道列表)中的getName (频道名称) 赋值给apArticle(文章信息)表中的ChannelName (频道名称)
        apArticle.setChannelName(adChannel.getName());
        apArticle.setChannelId(adChannel.getId());
        apArticle.setAuthorId(byId.getId().longValue());
        apArticle.setAuthorName(byId.getName());
        apArticle.setCreatedTime(wmNews.getCreatedTime());
        apArticle.setPublishTime(wmNews.getPublishTime());
//        远程调用fegin 去执行saveArticle  对Article表的一个添加操作


//
        ApArticle apArticle1 = articlesfen.saveArticle(apArticle);
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("id", apArticle1.getId());
        map.put("publishTime", apArticle1.getPublishTime());
        map.put("layout", apArticle1.getLayout());
        map.put("images", apArticle1.getImages());
        map.put("authorId", apArticle1.getAuthorId());
        map.put("title", apArticle1.getTitle());
        String string=JSON.toJSONString(apArticle1);
        IndexRequest request=new IndexRequest("hotel").id(apArticle1.getId().toString()).source(JSON.toJSONString(map), XContentType.JSON);
        request.source(string, XContentType.JSON);
        client.index(request, RequestOptions.DEFAULT);


        return apArticle1;

    }

    public void saveArticleconfig(WmNews wmNews, ApArticle apArticle) {
//      把ap_article（文章信息）赋值给ap_article_config
        ApArticleConfig apArticleConfig = new ApArticleConfig();
        apArticleConfig.setArticleId(apArticle.getId());

        apArticleConfig.setIsDown(false);
        apArticleConfig.setIsDelete(false);
        apArticleConfig.setIsForward(true);
        apArticleConfig.setIsComment(true);
//        对Articleconfig 表进行单表添加
        ResponseResult result = articlesfen.saveArticleConfig(apArticleConfig);
    }

    public void saveArticlecontenet(WmNews wmNews, ApArticle apArticle) {
        //      把ap_article（文章信息）赋值给ap_article_content
        ApArticleContent apArticleContent = new ApArticleContent();
        apArticleContent.setArticleId(apArticle.getId());
        apArticleContent.setContent(wmNews.getContent());
//        对ArticleContent 表进行单表添加
        ResponseResult result = articlesfen.saveArticleContent(apArticleContent);


    }
}
